/*
 * PhotonRTOS础光实时操作系统 -- AUTOSAR任务接口
 *
 * Copyright (C) 2022, 2023 国科础石(重庆)软件有限公司
 *
 * 作者: Baoyou Xie <xiebaoyou@kernelsoft.com>
 *
 * License terms: GNU General Public License (GPL) version 3
 *
 */

#ifndef OS_TASK_H
#define OS_TASK_H

#include <autosar/task_types.h>
#include <autosar/task_config.h>
#include <autosar/system_types.h>


/**
 * 任务状态:
 *     INVALID_STATE：错误状态，此时系统应该异常。
 *          可能是内存方面的严重错误。
 *     SUSPENDED：挂起状态
 *     READY：就绪状态
 *     RUNNING：运行状态
 *     WAITING：等待资源状态
 */
#define INVALID_STATE 0xFFUL
#define READY (1 << 1)
#define RUNNING (1 << 2)
#define WAITING (1 << 3)
#define SUSPENDED (1 << 4)

struct osek_task_attr {
	/**
	 * 任务标志，例如是否为扩展任务
	 */
	int32_t flags;
	/**
	 * 任务入口函数
	 */
	void (*entry)(void);
	/**
	 * 任务优先级，分别为静态定义的优先级和运行时优先级
	 * 在任务持有资源，
	 * 其运行时优先级将根据优先级
	 * 上限协议提升到最高优先级
	 */
	int32_t prio;
	/**
	 * 应用模式
	 */
	AppModeType app_mode;
	/**
	 * 是否自动启动
	 */
	int32_t auto_start;
	/**
	 * 绑定的处理器核心ID
	 */
	int32_t core_id;
	/**
	 * 任务调度策略
	 */
	int sched_policy;

	/**
	 * os-application 的id
	 */
	uint32_t app_id;
	/**
	 * 距离上一次激活任务的最短时间限制
	*/
	uint64_t cp_task_time_frame;

	/**
	 * 两次2类中断发生的最短时间间隔
	*/
	uint64_t  cp_isr_time_frame;
	/**
	 * cp 任务的预算总执行时间
	*/
	uint64_t cp_task_execution_budget;

	/**
	 * cp 中断处理程序ISR的预算总执行时间
	*/
	uint64_t cp_isr_execution_budget;
};


/**
 * 将任务<TaskID>从挂起状态转换为就绪状态。
 * 操作系统确保任务代码从其第一行开始执行。
 *  语法：
 *      StatusType ActivateTask ( TaskType <TaskID> )
 *  参数（输入）：
 *      TaskID	任务引用
 * 参数（输出）：
 *      无
 *  特殊说明：
 *      该服务可能从中断级或者任务级被调用。
 *      在ActivateTask调用后，重调度依赖于
 *      它被调用的位置（ISR、不可抢占任务、可抢占任务）。
 *      如果E_OS_LIMIT被返回，激活操作被忽略。
 *      当一个扩展任务从挂起状态转换到
 *      就绪状态时，它的所有事件被清除。
 * 状态：
 *      标准：
 *          无错误，E_OK
 *          太多任务被激活，E_OS_LIMIT
 *      扩展：
 *          任务<TaskID>无效，E_OS_ID
 *  一致性：
 *      BCC1, BCC2, ECC1, ECC2
 */
extern FUNC(StatusType, OS_CODE) ActivateTask(
	VAR(TaskType,AUTOMATIC)TaskID);

/**
 * 这个服务导致调用任务被终止。
 * 在调用任务被终止后，任务<TaskID>被激活。
 * 使用该服务，它确保在调用任务被终止后，
 * 后续任务开始在最初始地方运行。
 * 语法：
 *     StatusType ChainTask ( TaskType <TaskID> )
 * 参数（输入）：
 *     TaskID	 对随后将被激活任务的引用
 * 参数（输出）：
 *     无
 * 特殊说明：
 *     如果后续任务被标识为当前任务，
 *     它并不会导致多个请求。
 *     任务并不会转换为挂起状态，
 *     而是立即变成就绪状态。
 *     分配给调用任务的内部资源被自动释放，
 *     即使后续任务被标识为当前任务也是如此。
 *     其他由当前任务占据的资源必须
 *     在ChainTask被调用前释放。
 *     如果某个资源仍然被占据为标准状态，
 *     其行为是未定义的。
 *     如果调用成功，ChainTask并不会返回到调用者，
 *     其结果状态不能被评估。
 *     在错误时，服务返回到调用任务，
 *     并且提供一个状态，该状态可以被调用者判断。
 *     如果ChainTask调用成功，它会确保产生重调度。
 *     不调用TerminateTask或者ChainTask就结果一个任务函数，
 *     这是严格禁止的，并且可能将系统置于未定义状态。
 *     如果E_OS_LIMIT被返回，激活过程被忽略。
 *     当一个扩展任务从挂起状态转换为就绪状态，
 *     它的所有事件被清除。
 * 状态：
 *     标准：
 *          不返回到调用者
 *          太多任务被激活，E_OS_LIMIT
 *     扩展：
 *          任务<TaskID>无效，E_OS_ID
 *          调用任务占据资源，E_OS_RESOURE
 *          在中断级调用，E_OS_CALLEVEL
 * 一致性：
 *     BCC1, BCC2, ECC1, ECC2
 */
extern FUNC(StatusType, OS_CODE) ChainTask(
	VAR(TaskType, AUTOMATIC)TaskID);

/**
 * 返回当前正在运行任务的TaskID信息。
 * 语法：
 *     StatusType GetTaskID ( TaskRefType <TaskID> )
 * 参数（输入）：
 *     无
 * 参数（输出）：
 *     对当前正在运行任务的引用
 * 特殊说明：
 *     允许在任务级、ISR级以及内部钩子例程调用。
 *     该服务目的是用在库函数和钩子例程中。
 *     如果<TaskID>不能被计算(没有任务在运行)，
 *     服务返回INVALID_TASK作为TaskType。
 * 状态：
 *     标准：
 *        没有错误，E_OK
 *     扩展：
 *        没有错误，E_OK
 * 一致性：
 *     BCC1, BCC2, ECC1, ECC2
 */
extern FUNC(StatusType, OS_CODE) GetTaskID(
	VAR(TaskRefType, AUTOMATIC) TaskID);

/**
 * 返回在调用GetTaskState时，
 * 任务（运行、就绪、等待、挂起）状态。
 * 语法：
 *     StatusType GetTaskState ( TaskType <TaskID>, TaskStateRefType <State> )
 * 参数（输入）：
 *     TaskID	任务引用
 * 参数（输出）：
 *     State	对任务<TaskID>状态的引用
 * 特殊说明：
 *     允许在中断服务程序、任务级、
 *     以及某些钩子例程中调用该服务。
 *     当在全抢占系统任务中调用时，
 *     在判断结果的时候，其结果可能已经不正确。
 *     当针对任务调用该服务，而任务被激活不止一次，
 *     并且如果任务的某个实例正在运行，
 *     则结果状态被设置为运行状态。
 * 状态：
 *     标准：
 *        没有错误，E_OK
 *     扩展：
 *        任务<TaskID>无效，E_OS_ID
 * 一致性：
 *     BCC1, BCC2, ECC1, ECC2
 */
extern FUNC(StatusType, OS_CODE) GetTaskState(
	VAR(TaskType, AUTOMATIC) TaskID,
	VAR(TaskStateRefType, AUTOMATIC) State);

/**
 * 该服务导致调用任务被终止。
 * 调用任务从运行状态转换为挂起状态。
 * 语法：
 *     StatusType TerminateTask ( void )
 * 参数（输入）：
 *     无
 * 参数（输出）：
 *     无
 * 特殊说明：
 *      分配给调用任务的内部资源被自动释放。
 *      被任务占据的其他资源应当在
 *        调用TerminateTask之前被释放。
 *      如果某个资源仍然被占据为标准状态，
 *      那么其行为是未定义的。
 *      如果调用成功，TerminateTask不再返回到调用者，
 *      并且不能评估返回状态。
 *      如果扩展状态被使用，在错误情况下服务会返回，
 *      并且提供一个状态，该状态可以被应用所评估。
 *      如果TerminateTask服务被调用成功，
 *      它会确保产生重调度。
 *      不调用TerminateTask或者ChainTask而结束一个任务，
 *      这是严格禁止的，并且可能会将系统置于未定义状态。
 * 状态：
 *     标准：
 *        不返回到调用者
 * 扩展：
 *        任务仍然占据资源，E_OS_RESOURE
 *        在中断级调用，E_OS_CALLEVEL
 * 一致性：
 *     BCC1, BCC2, ECC1, ECC2
 */
extern FUNC(StatusType, OS_CODE)TerminateTask(void);

#if defined(AUTOSAR_SHOW_TASK_INFO)
#define ALL_TASK 	(0xFFFFUL)
#define EXT_INFO	0x0U
#define BASE_INFO	0x1U

#define INVALID_CORE_ID		0xFFFFFFFF
#define INVALID_APP_ID		0xFFFFFFFFU

/**
 * 显示任务信息
 * base:    BASE_INFO(基本信息)，EXT_INFO(拓展信息)
 * osek_id: ALL_TASK(所有任务)，0,1,2...
 * 
 * 显示所有任务信息时，返回显示的任务数
 * 显示指定任务信息时，返回osek_id表示显示失败，返回osek+1表示显示成功
 */
FUNC(uintptr_t, OS_CODE) ShowTaskInfo(
	VAR(uint32_t, AUTOMATIC) base,
	VAR(uintptr_t, AUTOMATIC) osek_id);

FUNC(void, OS_CODE) ShowAllTaskInfo(void);
#endif /* defined(AUTOSAR_SHOW_TASK_INFO) */


#if defined(AUTOSAR_OS_APPLICATION)
/*
 * 语法
 * void ActivateTaskAsyn (
 *      TaskType id
 * )
 *
 * 服务 ID [hex]
 *      0x33
 *
 * 同步/异步
 *      异步（Asynchronous ）
 *
 * 可重入性
 *      可重入
 *
 * 参数 (in)
 *      id
 *      待激活任务的id
 *
 * 参数 (inout)
 *      None
 *
 * 参数 (out)
 *      None
 *
 * 返回值
 *      None
 *
 * 描述
 *      ActivateTask() 函数的异步版本。旨在用于跨核心任务激活。可能的错误
 * 不会返回给调用者，但可能会通过错误钩子报告。
 *
 * 引用
 *      AUTOSAR OS 8.4.38 ActivateTaskAsyn [SWS_Os_91022]
 */
FUNC(void, OS_CODE) ActivateTaskAsyn(
	VAR(TaskType, AUTOMATIC) id);
#endif /* AUTOSAR_OS_APPLICATION */

/**
 * 如果一个高优先级任务就绪
 * 任务的内部资源将被释放，当前任务进入就绪状态
 * 其上下文将被保存，并且高优先级任务被执行。
 * 否则调用任务继续运行。
 * 语法：
 *     StatusType Schedule ( void )
 * 参数（输入）：
 *     无
 * 参数（输出）：
 *     无
 * 特殊说明：
 *     只有在系统生成期间将内部资源分配给调用任务时，
 *		才会发生重新调度。
 *     对这些任务，Schedule允许处理器分配给
 *		另外一个内部资源上限优先级相同或者
 *		更低任务，并且比应用特定优先级更高。
 *     当从Schedule返回时，内部资源被重新获取。
 *     在没有分配内部资源（可抢占任务），
 *		该服务对任务没有影响。
 * 状态：
 *     标准：
 *        没有错误，E_OK
 *     扩展：
 *        在中断级别调用，E_OS_CALLEVEL
 *        调用任务占据资源，E_OS_RESOURE
 * 一致性：
 *     BCC1, BCC2, ECC1, ECC2
 */
extern FUNC(StatusType, OS_CODE) Schedule(void);

#endif /* OS_TASK_H */
